package com.wugh.fast.module.api.bo;

import com.google.common.base.CaseFormat;
import com.wugh.fast.kernel.validator.exception.FastValidationException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;


/**
 * 基本的分页查询对象
 *
 * @author WUGH
 * @date 2018/3/15
 */
@Getter
@Setter
@Accessors(chain = true)
@ApiModel("基本的分页查询业务对象")
public class BasePageQueryBO implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final int DEFAULT_PAGE_SIZE = 10;
    public static final int DEFAULT_PAGE_NUMBER = 1;
    public static final String ORDER_ASC = "ASC";
    public static final String ORDER_DESC = "DESC";
    @ApiModelProperty(value = "每页多少条记录,缺省值为10", example = "10")
    protected Integer pageSize;
    @ApiModelProperty(value = "第几页,缺省值为1,如果为0则不进行分页", example = "1")
    protected Integer pageNumber;
    @ApiModelProperty("排序字段")
    protected String sortName;
    @ApiModelProperty(value = "排序方式", allowableValues = "ASC,DESC")
    protected String sortOrder;
    @ApiModelProperty(value = "多字段集合")
    protected List<String> sortList;

    public BasePageQueryBO() {
        this.pageSize = BasePageQueryBO.DEFAULT_PAGE_SIZE;
        this.pageNumber = BasePageQueryBO.DEFAULT_PAGE_NUMBER;
    }

    /**
     * 设置页大小
     *
     * @param pageSize 每页多少条记录,缺省值为10
     * @return
     */
    public BasePageQueryBO setPageSize(Integer pageSize) {
        if (pageSize == null || pageSize <= 0) {
            throw new FastValidationException("非法页大小:" + pageSize);
        }
        this.pageSize = pageSize;
        return this;
    }

    /**
     * 设置页码
     *
     * @param pageNumber 第几页,缺省值为1,如果为0则不进行分页
     * @return
     */
    public BasePageQueryBO setPageNumber(Integer pageNumber) {
        if (pageNumber == null || pageNumber < 0) {
            throw new FastValidationException("非法页码:" + pageNumber);
        }
        this.pageNumber = pageNumber;
        return this;
    }

    /**
     * 设置排序字段
     *
     * @param sortName
     * @return
     */
    public BasePageQueryBO setSortName(String sortName) {
        if (StringUtils.isNotBlank(sortName)) {
            this.sortName = dealSortName(sortName);
        }
        return this;
    }

    /**
     * 设置排序方式(升序或降序)
     *
     * @param sortOrder
     * @return
     */
    public BasePageQueryBO setSortOrder(String sortOrder) {
        if (StringUtils.isNotBlank(sortOrder)) {
            this.sortOrder = dealSortOrder(sortOrder);
        }
        return this;
    }

    /**
     * 批量设置多个排序
     *
     * @param sortList
     * @return
     */
    public BasePageQueryBO setSortList(List<String> sortList) {
        if (CollectionUtils.isNotEmpty(sortList)) {
            List<String> sorts = new ArrayList<>(sortList.size());
            for (String sort : sortList) {
                String[] arr = StringUtils.split(sort, " ", 2);
                if (arr.length == 0) {
                    continue;
                }
                String sortName = dealSortName(arr[0]);
                String sortOrder = dealSortOrder(arr.length > 1 ? arr[1] : null);
                sorts.add(sortName + " " + sortOrder);
            }
            this.sortList = sorts;
        }
        return this;
    }

    /**
     * 处理升序或降序
     *
     * @param sortOrder
     * @return
     */
    private String dealSortOrder(String sortOrder) {
        if (StringUtils.equalsIgnoreCase(sortOrder, ORDER_DESC)) {
            return ORDER_DESC;
        }
        return ORDER_ASC;
    }

    /**
     * 处理排序字段,如果想装换,或自定义装换则覆盖当前方法
     * <pre>
     *     默认是 LOWER_CAMEL -> LOWER_UNDERSCORE,则驼峰命名法转下划线
     * </pre>
     *
     * @param str
     * @return
     */
    protected String dealSortName(String str) {
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, str);
    }
}
